package model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import model.exceptions.*;


public class Equipo {
 
	public static final int CANTIDAD_JUGADORES_TOTAL_MIN = 15;
	
	public static final int CANTIDAD_JUGADORES_MISMO_CLUB_MAX = 4;
	
	public static final int CANTIDAD_JUGADORES_MISMA_POS_MIN = 2;
	
	public static final int COSTO_TOTAL_MAX = 100000;
	
	private String nombre;
	 
	private int costoTotal;
	 
	private int cantJugadores;
	 
	private List<Jugador> formacion;
	 
	private Participante participante;
	 
	public Equipo(){
		this.formacion = new ArrayList<Jugador>();
		this.setCantJugadores(0);
	}
	
	public void agregarJugador(Jugador jugador) {
		formacion.add(jugador);
		
		//Si agrego un Jugador, Actualizo la cantidad de jugadores
		int cantJugadores = this.getCantJugadores();
		this.setCantJugadores(++cantJugadores);
		
	}
	 
	public void cambiarJugador(Jugador jugadorEntra, Jugador jugadorSale) {
	
	}
	 
	public void quitarJugador(Jugador jugador) {
	 
	}

	protected int getCantJugadores() {
		return cantJugadores;
	}

	private void setCantJugadores(int cantJugadores) {
		this.cantJugadores = cantJugadores;
	}

	public int getCostoTotal() {
		return costoTotal;
	}

	public void setCostoTotal(int costoTotal) {
		this.costoTotal = costoTotal;
	}

	public List<Jugador> getFormacion() {
		return formacion;
	}

	public void setFormacion(List<Jugador> formacion) {
		this.formacion = formacion;
	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public Participante getParticipante() {
		return participante;
	}

	public void setParticipante(Participante participante) {
		this.participante = participante;
	}
	 
	/**
	 * 
	 * @return true indica que no se eligio mas del maximo de jugadores de un mismo club
	 */
	public boolean validarCantJugadoresDeUnClub() throws CantidadJugadoresPorClubException{		
		Map<String,Integer> clubes = new HashMap<String,Integer>(); 
		Integer cantidad = null;
		// Recorro todo el equipo para validar las reglas de club y puesto
		for (Iterator<Jugador> iter = this.getFormacion().iterator(); iter.hasNext();) {
			Jugador jugador = (Jugador) iter.next();
			
			// verifico el club
			if (clubes.get(jugador.getClub().getNombre()) == null){
				clubes.put(jugador.getClub().getNombre(), 1);
			} 
			else{
				cantidad = (Integer)clubes.get(jugador.getClub().getNombre());
				clubes.put(jugador.getClub().getNombre(),cantidad.intValue() + 1);
			}			
		}
		
		//Recorro el mapa de club elegidos y veo si alguno tiene mas de la cantidad maxima permitida
		boolean superoElLimite = false;
		Collection<Integer> cantJugadoresPorClub = clubes.values();//Obtengo todas las cantidades
		for (Iterator<Integer> iterator = cantJugadoresPorClub.iterator(); iterator.hasNext() && !superoElLimite;) {
			Integer integer = (Integer) iterator.next();
			if(integer.intValue() > Equipo.CANTIDAD_JUGADORES_MISMO_CLUB_MAX){
				superoElLimite = true;
				throw new CantidadJugadoresPorClubException("Se supero el limite de jugadores de un mismo club por equipo.");
			}			
		}
	
		//si no supera el limite debe retornar true
		return !superoElLimite;
	}

	
	/**
	 * 
	 * @return true indica que no se eligio mas del maximo de jugadores de un mismo club
	 */
	public boolean validarCantJugadoresPorPosicion() throws CantidadJugadoresPorPuestoException{
		Map<Integer,Integer> posiciones = new HashMap<Integer,Integer>(); 
		Integer cantidad = null;
		// Recorro todo el equipo para validar la regla del puesto
		for (Iterator<Jugador> iter = this.getFormacion().iterator(); iter.hasNext();) {
			Jugador jugador =  iter.next();
			
			// verifico la posicion
			if (posiciones.get(jugador.getPosicion().getTipo()) == null){
				posiciones.put(jugador.getPosicion().getTipo(), 1);
			} 
			else{
				cantidad = (Integer)posiciones.get(jugador.getPosicion().getTipo());
				posiciones.put(jugador.getPosicion().getTipo(),cantidad.intValue() + 1);
			}			
		}
		
		//Recorro el mapa de posiciones elegidas y veo si alguno tiene menos de la cantidad minima permitida
		boolean superoElLimite = true;
		Collection<Integer> cantJugadoresPorPuesto = posiciones.values();//Obtengo todas las cantidades
		for (Iterator<Integer> iterator = cantJugadoresPorPuesto.iterator(); iterator.hasNext() && superoElLimite;) {
			Integer integer = (Integer) iterator.next();
			if(integer.intValue() < Equipo.CANTIDAD_JUGADORES_MISMA_POS_MIN){
				superoElLimite = false;
				throw new CantidadJugadoresPorPuestoException("No se alcanzo la cantidad minima de jugadores por puesto.");
			}			
		}

		return superoElLimite;
	}
	
	
	/**
	 * @return Si el costo total del equipo no supera el limite retorna true, de lo contrario false.
	 */	
	public boolean validarCostoEquipo() throws CostoEquipoException{
		boolean esValida = true;		

		if(this.getCostoTotal() > Equipo.COSTO_TOTAL_MAX){
			esValida = false;
			throw new CostoEquipoException("Se supero el costo maximo por equipo.");
		}
		
		return esValida;	
	}
	
	
	/**
	 * @return Si la cantidad de Jugadores que contiene la formacion no alcanza la minima dara false.
	 */
	public boolean validarCantidadMinimaJugadoresPorEquipo() throws CantidadJugadoresPorEquipoException{
		boolean esValida = true;
		if(this.getCantJugadores() < Equipo.CANTIDAD_JUGADORES_TOTAL_MIN){
			esValida = false;
			throw new CantidadJugadoresPorEquipoException("No se alcanzo la cantidad minima de jugadores por equipo.");
		}
		
		return esValida;
	}
	 
}
 
